﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using GCELibrary.Current;

namespace ZF.BLL.Page
{
    public class MasterPage : System.Web.UI.MasterPage
    {
                #region 属性
        /// <summary>
        /// 站点API类
        /// </summary>
        public virtual SiteInfo SiteInfo
        {
            get
            {

                return SiteInfo.Instance;

            }
        }
        /// <summary>
        /// 报告生成器
        /// </summary>
        public virtual WarnFactory WarnFactory { get { return SiteInfo.WarnFactory; } }
  
        /// <summary>
        /// 当前页面的参数
        /// </summary>
        protected NameValueCollection PageArgument
        {
            get;
            set;
        }
        /// <summary>
        /// 当前页面的操作行为
        /// </summary>
        [PageArgument(Key="ot",DefaultValue=PageOperType.None)]
        public virtual PageOperType OperType { get; set; }
        /// <summary>
        /// 是否开启自动绑定成员与页面的参数值
        /// </summary>
        public virtual bool AutoBindPageArgument { get; set; }

        private string _WarnPage="~/warn.aspx";
        public virtual string WarnPage { get { return "_WarnPage"; } set { _WarnPage = value; } }

        #endregion

        #region 继承
        public MasterPage()
            : base() 
        {
            AutoBindPageArgument = true;
            
            
 
        }
        protected override void FrameworkInitialize()
        {
            base.FrameworkInitialize();
            OnLoadPageArgument(this, null);
        }
        #endregion

        #region 页面参数
        public virtual void OnLoadPageArgument(object sender,EventArgs e)
        {
            if(this.PageArgument==null)
                this.PageArgument=new NameValueCollection();
            for(int i=0;i<Request.QueryString.Count;i++)
            {
                var key=Request.QueryString.GetKey(i);
                var values=Request.QueryString.GetValues(i);
                foreach (var value in values)
                {
                    this.PageArgument.Add(key, value);
                }
            }
            if(this.AutoBindPageArgument){
                SetPropertiesPageArgument();
                SetFieldsPageArgument();
            }
        }
        /// <summary>
        /// 设置页面属性的参数，成员必须为字段为属性，且带有PageArgumentAttribute元数据
        /// </summary>
        private void SetPropertiesPageArgument()
        {
            var type = this.GetType();
            var memberArr = type.GetProperties().OrderBy(p => p.Name != "OperType").ToList();
            foreach (var mi in memberArr)
            {
                var objArr = mi.GetCustomAttributes(typeof(PageArgumentAttribute), true);
                if (objArr.Length > 0)
                {
                    PageArgumentAttribute pa = (PageArgumentAttribute)objArr[0];
                    var values = this.PageArgument.GetValues(pa.Key);//这里的key不分大小写
                    if (values != null && values.Length > 0)
                    {//找到相关参数
                        object oValue = null;
                        if (mi.PropertyType.BaseType == typeof(Array))
                            oValue = values;
                        else
                            oValue = values[0];
                        bool matchOper = true;//是否为成员赋值 
                        //如果当前成员设置了与页面操作类型绑定，则判断当前页面操作类型是相匹配
                        if (pa.BindOperType != PageOperType.None)
                        {
                            if ((this.OperType & pa.BindOperType) != 0)
                                matchOper = true;
                            else
                                matchOper = false;
                        }
                        
                        if (matchOper)
                        {
                            try
                            {
                                if (mi.PropertyType.IsEnum)//如果类型为枚举
                                    oValue = Enum.Parse(mi.PropertyType, values[0]);
                                else
                                    oValue = Convert.ChangeType(values[0], mi.PropertyType);
                            }
                            catch (Exception ex)
                            {
                                throw SiteInfo.WarnFactory.CreateWarn("页面参数格式错误");
                            }
                            mi.SetValue(this, oValue, null);
                        }

                    }
                    else
                    {//未找到参数
                        if (pa.BindOperType != PageOperType.None)
                        {//如果成员参数与页面操作方式
                            //匹配是否与当前的操作方式相匹配，
                            if ((this.OperType & pa.BindOperType) != 0)
                            {
                                if (!pa.CanNull)
                                {//如果该字段设置不允许为空则抛出异常，如果元数据未提供异常说明，则使用默认异常说明
                                    throw SiteInfo.WarnFactory.CreateWarn(pa.ErrorMsg.EmptyString("缺少参数"));
                                }
                                else if (pa.DefaultValue != null)
                                {//如果设置了默认值，则使用默认值赋值 
                                    mi.SetValue(this, pa.DefaultValue, null);
                                }
                            }
                        } 
                        else
                        {//未绑定页面操作方式
                            if (!pa.CanNull)
                            {//如果该字段设置不允许为空则抛出异常，如果元数据未提供异常说明，则使用默认异常说明
                                throw SiteInfo.WarnFactory.CreateWarn(pa.ErrorMsg.EmptyString("缺少参数"));
                            }
                            else if (pa.DefaultValue != null)
                            {//如果设置了默认值，则使用默认值赋值
                                mi.SetValue(this, pa.DefaultValue, null);
                            }
                        }
                    } 
                }
            }
        }
        /// <summary>
        /// 设置页面字段的参数，成员必须为字段为属性，且带有PageArgumentAttribute元数据
        /// </summary>
        private void SetFieldsPageArgument()
        {
            var type = this.GetType();
            var memberArr = type.GetFields();
            foreach (var mi in memberArr)
            {
                var objArr = mi.GetCustomAttributes(typeof(PageArgumentAttribute), true);
                if (objArr.Length > 0)
                {
                    PageArgumentAttribute pa = (PageArgumentAttribute)objArr[0];
                    var values = this.PageArgument.GetValues(pa.Key);//这里的key不分大小写
                    if (values != null && values.Length > 0)
                    {//找到相关参数
                        object oValue = null;
                        if (mi.FieldType.BaseType == typeof(Array))
                            oValue = values;
                        else
                            oValue = values[0];
                        bool matchOper = true;//是否为成员赋值 
                        //如果当前成员设置了与页面操作类型绑定，则判断当前页面操作类型是相匹配
                        if (pa.BindOperType != PageOperType.None)
                        {
                            if ((this.OperType & pa.BindOperType) != 0)
                                matchOper = true;
                            else
                                matchOper = false;
                        }
                        if (matchOper)
                        {
                            try
                            {
                                if (mi.FieldType.IsEnum)//如果类型为枚举
                                    oValue = Enum.Parse(mi.FieldType, values[0]);
                                else
                                    oValue = Convert.ChangeType(values[0], mi.FieldType);
                            }
                            catch (Exception ex)
                            {
                                throw SiteInfo.WarnFactory.CreateWarn("页面参数格式错误");
                            }
                            mi.SetValue(this, oValue);
                        }

                    }
                    else
                    {//未找到参数
                        if (pa.BindOperType != PageOperType.None)
                        {//如果成员参数与页面操作方式
                            //匹配是否与当前的操作方式相匹配，
                            if ((this.OperType & pa.BindOperType) != 0)
                            {
                                if (!pa.CanNull)
                                {//如果该字段设置不允许为空则抛出异常，如果元数据未提供异常说明，则使用默认异常说明
                                    throw SiteInfo.WarnFactory.CreateWarn(pa.ErrorMsg.EmptyString("缺少参数"));
                                }
                                else if (pa.DefaultValue != null)
                                {//如果设置了默认值，则使用默认值赋值
                                    mi.SetValue(this, pa.DefaultValue);
                                }
                            }
                        }
                        else
                        {//未绑定页面操作方式
                            if (!pa.CanNull)
                            {//如果该字段设置不允许为空则抛出异常，如果元数据未提供异常说明，则使用默认异常说明
                                throw SiteInfo.WarnFactory.CreateWarn(pa.ErrorMsg.EmptyString("缺少参数"));
                            }
                            else if (pa.DefaultValue != null)
                            {//如果设置了默认值，则使用默认值赋值
                                mi.SetValue(this, pa.DefaultValue);
                            }
                        }
                    }
                }
            }
        }

        #endregion
    }
}
